package com.mashibing.class01;

/**
 * @Auther: huangxiaode
 * @Date: 2024-01-29 - 01 - 29 - 14:42
 * @Description: com.mashibing.class01
 * @version: 1.0
 */
public class Code06_PrintB {
    /**
     * 反码和补码
     * 对于一个32位的整数, 在计算机中可以表示的范围是 0 - (2的32次方减1)
     * 但是在计算机中,表示一个32位整数 最高位留着没有用, 表示有特殊意义的, 他所表示的最大值是 2的31次方减1
     * 因为他是有一半分给负数使用 实际表示的范围是 -2的31次方 到 2的31次方减1
     * 在计算机中 对于一个32位的整数, 最高位表示符号位, 0表示正数 1表示负数.
     * 如果是负数, 符号位是1 ,后面的数据状态取反加1.
     * -1 在计算机表示的32位数是 11111111111111111111111111111111
     *   32位数的最小数(-2的31次方)是:  10000000000000000000000000000000
     *  32位数的最大数(2的31次方减1)是: 01111111111111111111111111111111
     *  负的最小的绝对值 比 正的最大的绝对值 要大1
     *  非负领域 因为存在一个0, 导致正数领域 少了一个.
     *  负数可以到达2的31次方, 就是因为他没有0的负担, 因为0是归属于非负区域.
     *  为什么负数需要采用取反加1?
     *  计算机对于 加 减 乘 除, 里面采用的计算方式都是二进制的.
     *  a + b 加号翻译成位运算的方式; 当a 和 b 都为正数的时候,直接采用位运算即可
     *  而 当a是正数 b负数, 如果负数不取反的话,这个时候采用上述的位运算的方式行不通,
     *  为了 能让a位正数 b为负数, 能够采用相同的位运算逻辑, 所以计算机对于负数的存储 采用 取反加1的方式比较合适.
     */
    public static void print(int num){
        for (int i = 31; i >=0 ; i--) {
            System.out.print((num&(1<<i))==0?"0":"1");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        // 32位
     //   int num = Integer.MAX_VALUE;
      //  print(num);

        int a = Integer.MIN_VALUE;
        print(a);
        print(a>>1);// 带符号右移.
        print(a>>>1);// 不带符号右移

        int c = 5;
        int d = -c;
        int d1 = (~c +1);
        System.out.println("c = " + c);   // 5
        System.out.println("d = " + d);   // -5
        System.out.println("d1 = " + d1); // -5
    }
}
